﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Medianamik.Core.DAL.SQL
{
    public class InsertClause : ISqlQueryPart
    {
        private List<KeyValuePair<Column, IExpression>> _columnValues;

        public InsertClause(IEnumerable<KeyValuePair<Column, IExpression>> pColumns)
        {
            _columnValues = pColumns.ToList();
            Validate();
        }

        public StringBuilder ToSQL()
        {
            var table = _columnValues[0].Key.Table;

            var builder = new StringBuilder()
            .AppendLine(" INSERT INTO [" + table.Schema + "].[" + table.Name + "] ( ");
           //Liste des colonnes
            builder.Append("[" + _columnValues.First().Key.Name + "]");
            foreach (var colVal in _columnValues.Skip(1))
            {
                builder.Append(", [" + colVal.Key.Name + "]");
            }

            builder.Append(" ) VALUES ( ");

            builder.Append( _columnValues.First().Value.ToSQL() );
            foreach (var colVal in _columnValues.Skip(1))
            {
                builder.Append(", " + colVal.Value.ToSQL() );
            }

            builder.Append(" )");

            return builder;

        }

        private void Validate()
        {
            if(_columnValues.Count == 0)
            {
                throw new CoreException("At least one column must be supplied"); 
            }
            var distinctTables = _columnValues.Select(p => p.Key.Table).Distinct(new TableComparer());
            if(distinctTables.Count() > 1 )
            {
                throw new CoreException("All columns must come from the same Table"); 
            }

        }

        private class TableComparer : IEqualityComparer<Table>
        {
            public bool Equals(Table x, Table y)
            {
                return string.Compare(x.Name, y.Name, true) == 0;  
            }

            public int GetHashCode(Table obj)
            {
                return obj.Name.ToLower().GetHashCode(); 
            }

        }
 
    }

    
}
